<?php

class fssUtil
{
    public static function module_item($title, $step, $options = null)
    {
        $request = sfContext::getInstance()->getRequest();
        $module = $request->getParameter('module');

        if (!is_array($step))
            $step = array($step);

        if (!$options)
            $options = array();
        if (isset($options['class']))
            $options['class'] .= ' ';
        else
            $options['class'] = '';

        if (in_array($module, $step))
            $options['class'] .= ' selected';

        $content = content_tag('span', $title, array('class' => 'title'));
        $content = content_tag('a', $content, $options);
        return content_tag('dt', $content);
    }

    public static function tab_item($title, $description, $step, $next = null, $options = null, $href = null)
    {
        $request = sfContext::getInstance()->getRequest();
        $action = $request->getParameter('action');

        if (!is_array($step))
            $step = array($step);

        if (!$options)
            $options = array();
        if (isset($options['class']))
            $options['class'] .= ' ';
        else
            $options['class'] = '';

        $options['class'] .= 'FB_Step';
        if (in_array($action, $step))
            $options['class'] .= ' FB_StepSelected';
        elseif ($action === $next)
            $options['class'] .= ' FB_StepNextSelected';

        $href && $request->hasParameter('campaign_id') ? $content = content_tag('a', $title, array('href' => $href.'?campaign_id='.$request->getParameter('campaign_id'))) : $content = $title;
        $content = content_tag('div', $content, array('class' => 'title')).content_tag('span', $description, array('class' => 'description'));
        $content = content_tag('div', $content, array('class' => 'content'));
        $content = content_tag('div', '', array('class' => 'part back'))
            .content_tag('div', $content, array('class' => 'part middle'))
            .content_tag('div', '', array('class' => 'part point'));
        return content_tag('li', $content, $options);
    }

    public static function doubleExplode ($del1, $del2, $array){
        $array1 = explode("$del1", $array);
        foreach($array1 as $key=>$value){
            $array2 = explode("$del2", $value);
            foreach($array2 as $key2=>$value2){
                $array3[] = $value2;
            }
        }
        $afinal = array();
        for ( $i = 0; $i < count($array3); $i += 2) {
            if($array3[$i]!=""){
                $afinal[trim($array3[$i])] = trim($array3[$i+1]);
            }
        }
        return $afinal;
    }

    public static function getTimestamp($datetime)
    {
        list($date, $time) = explode(' ', $datetime);
        list($year, $month, $day) = explode('-', $date);
        list($hour, $minute, $second) = explode(':', $time);
        $timestamp = mktime($hour, $minute, $second, $month, $day, $year);
        return $timestamp;
    }

    public static function generateRandomToken($base = '')
    {
        try {
            $base .= sfContext::hasInstance() ? sfContext::getInstance()->getUser()->getPageId() : '';
        } catch (Exception $e) {
            // If called from api there's no method getPageId on MyUser.
        }
        
        $base .= microtime().rand();
        
        return sha1($base);
    }

    /**
     * Runs a command for a given time, and kills it when timeout seconds
     * have passed since start_time.
     *
     * @param start_time float is the return value of microtime(true)
     * @param timeout, float, in seconds
     * @return true if the process completed successfully,
     *         false if the process was interrupted.
     */
    public static function exec($command, $start_time = null, $timeout = null)
    {
        sfContext::getInstance()->getLogger()->info("{fssUtil} exec: $command");

        $descriptorspecs = array(
            0 => array('pipe', 'r'),
            1 => array('pipe', 'w'),
            2 => array('pipe', 'w'),
            );
        $pipes = null;
        $cmd_start = microtime(true);
        $handle = proc_open($command, $descriptorspecs, $pipes);
        if (!$handle)
            throw new Exception("Error running command '$command'");

        // Optional timeout
        if ($start_time && $timeout) {
            // Account for elapsed time since start_time
            $cmd_timeout = $timeout - microtime(true) + $start_time;
            $tv_sec = 0;
            $tv_usec = ($cmd_timeout * 1000 * 1000);
            if ($tv_usec < 0)
                // Return immediately
                $tv_usec = 0;
            sfContext::getInstance()->getLogger()->info("{fssUtil} waiting for process for {$cmd_timeout}s...");
        } else {
            // Block indefinitely
            $tv_sec = null;
            $tv_usec = 0;
        }

        $read = array($pipes[2]); // wait on stderr
        $write = null;
        $except = null;
        $res = stream_select($read, $write, $except, $tv_sec, $tv_usec);

        if ($res === false) {
            throw new Exception("stream_select error");
        }

        $stdout = stream_get_contents($pipes[1]);
        $stderr = stream_get_contents($pipes[2]);
        
        if ($stderr) {
            vtnsLog::criticalWithBT('{fssUtil} stdout: %s', str_replace("\n", '\\n', $stdout));
            vtnsLog::criticalWithBT('{fssUtil} stderr: %s', str_replace("\n", '\\n', $stderr));
        } elseif ($stdout) {
            vtnsLog::debug('{fssUtil} stdout: %s', str_replace("\n", '\\n', $stdout));
        }

        proc_terminate($handle);
        $cmd_end = microtime(true);
        $time = $cmd_end - $cmd_start;

        if ($res == 0) {
            sfContext::getInstance()->getLogger()->info("{fssUtil} task interrupted after {$time}s");
        } else {
            sfContext::getInstance()->getLogger()->info("{fssUtil} task completed in {$time}s");
        }

        return ($res != 0);
    }


    public static function hasTimedOut($start_time, $timeout)
    {
        if (!$start_time)
            return false;
        $elapsed_time = microtime(true) - $start_time;
        if ($elapsed_time < $timeout)
            return false;
        sfContext::getInstance()->getLogger()->info("{fssUtil} Timeout after {$elapsed_time}s");
        return true;
    }


    public static function encodeUrlParam($data)
    {
        $param = rtrim(strtr(base64_encode(gzdeflate($data, 9)), '+/', '-_'), '=');

        $checksum = crc32($param) % 100;
        return $checksum.'.'.$param;
    }

    public static function decodeUrlParam($data)
    {
        @list($checksum,$param) = explode('.', $data);

        if (!empty($param)) {
            $check = crc32($param) % 100;
            if ($check == $checksum) {
                return gzinflate(base64_decode(strtr($param, '-_', '+/')));
            }
        }
        return '';
    }
}

